/*
我们发现，如果单纯使用Statement来执行sql命令，会存在严重的sql注入攻击漏洞，这种情况可以使用PreparedStatement预编译来防止SQL注入
参考这篇文章：https://xz.aliyun.com/t/10593
 */
package MyJDBC;

import java.sql.*;
import java.util.Scanner;

public class SQLInjectPrepared {
    public static void main(String[] args) {
        try(Connection connection = DriverManager.getConnection("jdbc:mysql://192.168.32.130:3306/study", "root", "123456");
            PreparedStatement preparedStatement = connection.prepareStatement("select * from user where username = ? and password = ?;");
            //使用PreparedStatement 创建预编译的statement，使用?占位符占位
            Scanner scanner = new Scanner(System.in)){
            preparedStatement.setString(1, scanner.nextLine());  //使用setString，接收输入设置为序号1,2占位符的值
            preparedStatement.setString(2, scanner.nextLine());
            System.out.println(preparedStatement);  //打印看下预编译后的组合sql语句
            ResultSet set = preparedStatement.executeQuery();
            while(set.next()){
                String username = set.getString(1);
                System.out.println(username+ "登录成功");
            }
        }catch (SQLException exception){
            exception.printStackTrace();
        }
    }
}
/*
    分别输入以下组合进行测试
    1、正确的用户名和密码
    2、错误的用户名和密码
    3、正确的用户名和密码为 1' or 1=1 --(空格) 的情况 select * from user where username = 'admin' and password = '1'' or 1=1 -- ';
    4、用户名为admin' or 1=1 -- ;  密码为空的情况 select * from user where username = 'admin'' or 1=1 -- ' and password = '123';
*/
/*
测试发现，PreparedStatement预编译，会自动给占位符的字符串加一对单引号，且如果遇到字符串里有单引号，会自动再给这个字符串加一个单引号形成空字符串闭合。
原理是：JDBC在ClientPreparedQueryBindings.setString()中对一些特殊符号包括'做了转义处理
 */
